package com.xp.ai.tools;


import com.xp.ai.util.ModelUtils;
import dev.langchain4j.agent.tool.*;
import dev.langchain4j.data.message.*;
import dev.langchain4j.memory.ChatMemory;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.chat.request.ChatRequest;
import dev.langchain4j.model.chat.request.ChatRequestParameters;
import dev.langchain4j.model.chat.response.ChatResponse;
import dev.langchain4j.service.tool.DefaultToolExecutor;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/***
 * 复习一下带工具的方法
 * 再加上对网络搜索的扩展
 */
public class WithToolsChat3 {


    static class Tools{
        @Tool("当前日期")
        public String now(){
            return LocalDateTime.now().toString();
        }

        @Tool("获取某个城市的天气情况")
        public String getWeather(@P("指定城市") String location){
            return "今天"+ location +"天气不错";
        }
    }

    public static void main(String[] args) {

        ChatLanguageModel chatLanguageModel = ModelUtils.getHuoshanv3Model();
        //构建对话记忆，将ArrayList 替换为MessageWindowChatMemory
        ChatMemory chatMemory = MessageWindowChatMemory.withMaxMessages(10);
        List<ToolSpecification> toolSpecifications = ToolSpecifications.toolSpecificationsFrom(Tools.class);
        ChatRequestParameters chatRequestParameters = ChatRequestParameters.builder()
                .toolSpecifications(toolSpecifications)
                //设置温度，值越大，越随机，越不固定，
                // 越能探索新领域，但是越不精确
                // 范围是 0-1
                .temperature(0.48)
                .build();

        //从系统层面给他赋予角色
        SystemMessage systemMessage = SystemMessage.from("请你扮演特朗普，并以特朗普的角度回答问题");
        chatMemory.add(systemMessage);

        UserMessage userMessage1 = UserMessage.from("今天几月几号？德阳的天气怎么样？");
        chatMemory.add(userMessage1);
        ChatRequest chatRequest = ChatRequest.builder()
                .messages(chatMemory.messages())
                .parameters(chatRequestParameters)
                .build();

        ChatResponse chatResponse1 = chatLanguageModel.chat(chatRequest);
        AiMessage aiMessage1 = chatResponse1.aiMessage();
        //一定不能漏掉每一条消息 必须得加进去
        chatMemory.add(aiMessage1);
        //是否需要调用工具？
        if (aiMessage1.hasToolExecutionRequests()) {
            List<ToolExecutionRequest> toolExecutionRequests = aiMessage1.toolExecutionRequests();

            Tools tools = new Tools();
            toolExecutionRequests.forEach(toolExecutionRequest -> {
                String name = toolExecutionRequest.name();
                String arguments = toolExecutionRequest.arguments();
                System.out.println(" 调用工具方法为："+ name);
                System.out.println(" 调用工具参数为："+ arguments);

                //构建本地方法执行器，这里就不用自己去反射调用了
                DefaultToolExecutor toolExecutor = new DefaultToolExecutor(tools, toolExecutionRequest);
                String result = toolExecutor.execute(toolExecutionRequest, UUID.randomUUID().toString());
                System.out.println("工具执行结果:"+result);

                //构建工具消息
                ToolExecutionResultMessage toolExecutionResultMessage = ToolExecutionResultMessage.from(toolExecutionRequest.id(), toolExecutionRequest.name(), result);
                chatMemory.add(toolExecutionResultMessage);
            });

            //再次发起对大模型的调用
            ChatRequest chatRequest2 = ChatRequest.builder()
                    .messages(chatMemory.messages())
                    .parameters(chatRequestParameters)
                    .build();
            ChatResponse chatResponse2 = chatLanguageModel.chat(chatRequest2);
            AiMessage aiMessage2 = chatResponse2.aiMessage();
            String finalResult = aiMessage2.text();
            System.out.println(finalResult);
        }


    }
}
